﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace Light.Aop
{
    class Helper
    {

        /// <summary>
        /// 缓存Key,由类完整名+方法名+参数MD5值（依赖Castle）
        /// </summary>
        /// <param name="invocation"></param>
        /// <returns></returns>
        public static string GetCacheKey(Castle.DynamicProxy.IInvocation invocation)
        {
            return invocation.InvocationTarget.ToString() + "_" + invocation.Method.Name + "_" + GetMD5(invocation.Arguments);
        }

        /// <summary>
        /// 缓存Key,由类完整名+方法名+参数MD5值
        /// </summary>
        /// <param name="invocation"></param>
        /// <returns></returns>
        public static string GetCacheKey(MethodBase method, object[] args)
        {
            return method.DeclaringType.ToString() + "_" + method.Name + "_" + GetMD5(args);
        }

        /// <summary>
        /// 获取缓存Key的前缀
        /// </summary>
        /// <param name="method"></param>
        /// <param name="attr"></param>
        /// <returns></returns>
        public static string GetKeyPrefix(MethodBase method, CacheMethodAttribute attr)
        {
            string keyPrefix = attr.KeyPrefix + (attr.Type != null ? attr.Type.Name : "");
            if (string.IsNullOrEmpty(keyPrefix) & (method.Name == "Create" || method.Name == "Update" || method.Name == "Delete"))
            {
                ParameterInfo[] pInfos = method.GetParameters();
                if (pInfos[0].ParameterType.IsGenericType)
                    keyPrefix = pInfos[0].ParameterType.GetGenericArguments()[0].Name;
                else if (!pInfos[0].ParameterType.Module.Name.Contains("mscorlib"))
                    keyPrefix = pInfos[0].ParameterType.Name;
            }
            return keyPrefix;
        }

        private static string GetMD5(object obj)
        {
            try
            {
                StringBuilder pwd = new StringBuilder();
                System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create();

                var ser = new ServiceStack.Redis.Support.ObjectSerializer();
                byte[] s = md5.ComputeHash(ser.Serialize(obj));

                for (int i = 0; i < s.Length; i++)
                {
                    pwd.Append(s[i].ToString("x").PadLeft(2, '0'));
                }
                return pwd.ToString();
            }
            catch (Exception ex)
            {
                Light.Utility.TextHelper.Console("aop.log", ex.Message, true);
                return obj.ToString();
            }

        }
    }
}
